package ufw

import (
	"bufio"
	"context"
	"fmt"
	"github.com/marcellowy/go-common/gogf/vlog"
	"github.com/marcellowy/go-common/tools"
	"io"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"
)

var filename = "/var/log/ufw.log"

func Start(ctx context.Context) {
	for {
		vlog.Info(ctx, "begin")
		p(ctx)
		time.Sleep(time.Second * 10)
	}
}

func p(ctx context.Context) {
	var err error
	var file *os.File
	if file, err = os.OpenFile(filename, os.O_RDONLY, 0666); err != nil {
		vlog.Error(ctx, err)
		return
	}
	defer tools.Close(file)

	vlog.Info(ctx, "seek")
	// 单行大小在 360 左右
	_, err = file.Seek(-4096, io.SeekEnd) // 从文件末尾向前偏移
	if err != nil {
		// 如果失败,也可能是文件没有65535个字节
		vlog.Error(ctx, err)
		return
	}

	vlog.Info(ctx, "bufio")
	// 开始从偏移后的位置读取内容
	scanner := bufio.NewScanner(file)

	regSrcIP := regexp.MustCompile("SRC=([0-9]+.[0-9]+.[0-9]+.[0-9]+)")
	//retDstPort := regexp.MustCompile("DPT=([0-9]+)")

	for scanner.Scan() {
		text := scanner.Text()
		// 2024-12-20T18:08:44.921580+08:00 unreal-beep-2 kernel: [416695.766149] [UFW BLOCK] IN=eth0 OUT=
		// MAC=aa:aa:00:1d:d7:58:d4:04:ff:84:cc:40:08:00 SRC=147.182.217.53 DST=23.106.158.67 LEN=44 TOS=0x00
		// PREC=0x00 TTL=241 ID=59384 PROTO=TCP SPT=61005 DPT=8001 WINDOW=1025 RES=0x00 SYN URGP=0
		if !strings.Contains(text, "UFW BLOCK") {
			continue
		}

		var srcIP string
		//var dstPort string

		// 提取源IP
		matchArr := regSrcIP.FindStringSubmatch(text)
		if len(matchArr) > 0 {
			srcIP = matchArr[1]
		}

		//matchArr = retDstPort.FindStringSubmatch(text)
		//if len(matchArr) > 0 {
		//	dstPort = matchArr[1]
		//}

		shell := fmt.Sprintf("ufw deny from %s", srcIP)
		cmd := exec.Command("sh", "-c", shell)
		if _, err = cmd.CombinedOutput(); err != nil {
			vlog.Error(ctx, err)
		}
	}
}
